package hos.okhttp.utils;

import android.text.TextUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;

import hos.http.HttpConstant;
import hos.http.converter.HttpConverterUtils;
import hos.http.retrofit.TypeUtil;
import hos.okhttp.exception.OkHttpException;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.ByteString;

/**
 * <p>Title: OkHttpResponseUtils </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-03-25 20:56
 */
public class OkHttpResponseUtils {

    public static Object requireData(Type succeed, Response response) throws IOException {

        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
        }
        if (TypeUtil.equals(succeed, Integer.class) && response.isSuccessful()) {
            return Integer.valueOf(responseBody.string());
        }
        if (TypeUtil.equals(succeed, Long.class)) {
            return Long.valueOf(responseBody.string());
        }
        if (TypeUtil.equals(succeed, Float.class)) {
            return Float.valueOf(responseBody.string());
        }
        if (TypeUtil.equals(succeed, Double.class)) {
            return Double.valueOf(responseBody.string());
        }
        if (TypeUtil.equals(succeed, Boolean.class)) {
            return Boolean.valueOf(responseBody.string());
        }
        if (TypeUtil.equals(succeed, String.class)) {
            return responseBody.string();
        }
        if (TypeUtil.equals(succeed, ByteString.class)) {
            return responseBody.byteString();
        }
        if (succeed instanceof GenericArrayType && ((GenericArrayType) succeed).getGenericComponentType() ==
                Byte.class && response.isSuccessful()) {
            return responseBody.bytes();
        }
        if (TypeUtil.equals(succeed, File.class)) {
            return OkHttpFileUtils.parseFile(response);
        }
        if (TypeUtil.equals(succeed, Response.class)) {
            return response;
        }
        throw OkHttpException.throwConverter(response.request());
    }

    public static String requireString(Response response) throws IOException {
        int responseCode = response.code();
        if (responseCode >= 200 && responseCode < 298) {
            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
            }
            return responseBody.string();
        } else if (responseCode >= 400 && responseCode < 498) {
            throw OkHttpException.throwParam(response.request());
        } else if (responseCode >= 500) {
            throw OkHttpException.throwServer(response.request());
        } else {
            throw OkHttpException.throwConverter(response.request());
        }
    }

    public static Response requireResponse(Response response) throws IOException {
        int responseCode = response.code();
        if (responseCode >= 200 && responseCode < 298) {
            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
            }
            return response;
        } else if (responseCode >= 400 && responseCode < 498) {
            throw OkHttpException.throwParam(response.request());
        } else if (responseCode >= 500) {
            throw OkHttpException.throwServer(response.request());
        } else {
            throw OkHttpException.throwConverter(response.request());
        }
    }

    public static String requireJson(
            Response response, String success
    ) throws IOException {
        return requireJson(response, success, "code", "msg");
    }

    public static String requireJson(
            Response response, String success, String code
    ) throws IOException {
        return requireJson(response, success, code, "msg");
    }

    public static String requireJson(
            Response response
    ) throws IOException {
        return requireJson(response, "200", "code", "msg");
    }

    public static String requireJson(
            Response response,
            String success, String code, String message
    ) throws IOException {
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
        }
        String jsonResponse = responseBody.string();
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (TextUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                return jsonResponse;
            } else {
                // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, HttpConstant.SERVER_ERROR);
                // 将业务错误码作为tag传递
                throw OkHttpException.throwResult(response.request(), errorMessage);
            }
        } catch (JSONException e) { // 固定格式JSON分析失败直接解析JSON
            throw OkHttpException.throwConverter(response.request(), e);
        }
    }


    public static String requireJsonData(
            Response response
    ) throws IOException {
        return requireJsonData(response, "200", "code", "msg", "data");
    }

    public static String requireJsonData(
            Response response,
            String success
    ) throws IOException {
        return requireJsonData(response, success, "code", "msg", "data");
    }

    public static String requireJsonData(
            Response response,
            String success, String code
    ) throws IOException {
        return requireJsonData(response, success, code, "msg", "data");
    }

    public static String requireJsonData(
            Response response,
            String success, String code, String message
    ) throws IOException {
        return requireJsonData(response, success, code, message, "data");
    }

    public static String requireJsonData(
            Response response,
            String success, String code, String message,
            String data
    ) throws IOException {
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
        }
        String jsonResponse = responseBody.string();
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (TextUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                return json.optString(data);
            } else { // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, HttpConstant.SERVER_ERROR);
                // 将业务错误码作为tag传递
                throw OkHttpException.throwResult(response.request(), errorMessage);
            }
        } catch (JSONException e) { // 固定格式JSON分析失败直接解析JSON
            throw OkHttpException.throwConverter(response.request(), e);
        }
    }

    public static Object convertListMap(Response response) throws IOException {
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
        }
        String jsonResponse = responseBody.string();
        try {
            if (jsonResponse.startsWith("{") && jsonResponse.endsWith("}")) {
                return HttpConverterUtils.parseMap(jsonResponse);
            } else {
                return HttpConverterUtils.parseList(jsonResponse);
            }
        } catch (Exception e) {
            throw OkHttpException.throwConverter(response.request(), e);
        }
    }

    public static Object convertListMap(Response response, String json) throws IOException {
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            throw OkHttpException.throwConverter(response.request(), new NullPointerException("responseBody is null"));
        }
        try {
            if (json.startsWith("{") && json.endsWith("}")) {
                return HttpConverterUtils.parseMap(json);
            } else {
                return HttpConverterUtils.parseList(json);
            }
        } catch (Exception e) {
            throw OkHttpException.throwConverter(response.request(), e);
        }
    }
}
